package com.smile.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.dtflys.forest.annotation.Get;
import com.smile.api.OperateLogApi;
import com.smile.api.OrganizationApi;
import com.smile.api.OssApi;
import com.smile.commons.action.ActionUtils;
import com.smile.commons.page.MyBatisPlusPageConverter;
import com.smile.commons.page.R;
import com.smile.commons.time.TimeUtils;
import com.smile.mapper.AirportDroneMapper;
import com.smile.mapper.AirportMapper;
import com.smile.mapper.DroneMapper;
import com.smile.model.domain.FeisuanAirport;
import com.smile.model.domain.FeisuanAirportDrone;
import com.smile.model.domain.FeisuanDrone;
import com.smile.model.dto.DroneDTO;
import com.smile.model.dto.request.*;
import com.smile.model.response.response.GetAirportByIdResponseDTO;
import com.smile.model.response.response.GetAirportListResponseDTO;
import com.smile.model.request.GetOrganizationByIdRequest;
import com.smile.model.response.GetOrganizationByIdResponse;
import com.smile.request.AddOperateLogRequest;
import com.smile.service.AirportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AirportServiceImpl implements AirportService {

    @Autowired
    private OssApi ossApi;

    @Autowired
    private AirportMapper airportMapper;

    @Autowired
    private OperateLogApi operateLogApi;

    @Autowired
    private AirportDroneMapper airportDroneMapper;

    @Autowired
    private DroneMapper droneMapper;

    @Autowired
    private OrganizationApi organizationApi;

    private ReentrantLock reentrantLock = new ReentrantLock();

    @Override
    @Transactional
    public Boolean addAirport(AddAirportRequestDTO addAirportRequestDTO) throws IOException {
        try {
            reentrantLock.lock();

            Long startTime = System.nanoTime();

            // 1. 创建机场对象并设置基础属性
            FeisuanAirport feisuanAirport = new FeisuanAirport();
            BeanUtil.copyProperties(addAirportRequestDTO, feisuanAirport);

//        // 2. 处理机场图片
//        String fileName = IdWorker.getIdStr() + ".jpg";
//        R<PutFileResponse> putFileResponseR = ossApi.putFile("photo/airport", fileName, addAirportRequestDTO.getAirportImage());
//
//        // 修正图片上传判断逻辑
//        if (putFileResponseR != null && putFileResponseR.getCode() == 200 && putFileResponseR.getData() != null) {
//            feisuanAirport.setAirportImageUrl(fileName);
//        } else {
//            // 可以添加日志记录上传失败，或使用默认图片
//            log.error("机场图片上传失败: {}", putFileResponseR);
//        }

            // 3. 设置其他属性
            feisuanAirport.setCreateTime(LocalDateTime.now());
            feisuanAirport.setModifyTime(LocalDateTime.now());
            feisuanAirport.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
            feisuanAirport.setStatus(1);
            feisuanAirport.setTotalTaskCount(0L);
            feisuanAirport.setTotalTaskTime(0L);
            feisuanAirport.setDeleteStatus(false);
            feisuanAirport.setTotalTaskDistance(0L);

            // 4. 保存机场信息
            airportMapper.insert(feisuanAirport);

            // 5. 处理关联的无人机（新增绑定状态检查）
            List<Long> droneIds = addAirportRequestDTO.getDroneIds();
            if (CollUtil.isNotEmpty(droneIds)) {
                // 5.1 检查无人机绑定状态
                QueryWrapper<FeisuanAirportDrone> bindCheckWrapper = new QueryWrapper<>();
                bindCheckWrapper.in("drone_id", droneIds)
                ; // 假设0表示未删除

                List<FeisuanAirportDrone> existingBinds = airportDroneMapper.selectList(bindCheckWrapper);

                // 5.2 收集已绑定的无人机ID
                Set<Long> boundDroneIds = existingBinds.stream()
                        .map(FeisuanAirportDrone::getDroneId)
                        .collect(Collectors.toSet());

                // 5.3 找出未绑定的无人机
                List<Long> validDroneIds = droneIds.stream()
                        .filter(droneId -> !boundDroneIds.contains(droneId))
                        .collect(Collectors.toList());

                // 5.4 如果有重复绑定，记录日志或抛出异常
                if (validDroneIds.size() != droneIds.size()) {
                    log.warn("检测到{}架无人机已绑定，跳过绑定: {}",
                            droneIds.size() - validDroneIds.size(),
                            droneIds.stream()
                                    .filter(boundDroneIds::contains)
                                    .collect(Collectors.toList()));
                }

                // 5.5 只保存未绑定的无人机
                if (CollUtil.isNotEmpty(validDroneIds)) {
                    List<FeisuanAirportDrone> relations = validDroneIds.stream()
                            .map(droneId -> {
                                FeisuanAirportDrone relation = new FeisuanAirportDrone();
                                relation.setAirportId(feisuanAirport.getId());
                                relation.setDroneId(droneId);
//                            relation.(false); // 设置删除状态
                                return relation;
                            })
                            .collect(Collectors.toList());

                    // 批量保存关联关系
                    Db.saveBatch(relations);
                }
            }

            // 6. 记录操作日志
            Long endTime = System.nanoTime();
            AddOperateLogRequest addOperateLogRequest = new AddOperateLogRequest();
            addOperateLogRequest.setOperateModule("设备模块");
            addOperateLogRequest.setOperateName("新增机场");
            addOperateLogRequest.setOperateResult(Boolean.TRUE);
            addOperateLogRequest.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
            addOperateLogRequest.setOperateType(1);
            addOperateLogRequest.setIpAddress(ActionUtils.getIpInfo());
            addOperateLogRequest.setExplorer(ActionUtils.getExplorerInfo());
            addOperateLogRequest.setTimes(endTime - startTime);
            operateLogApi.addOperateLogRequest(addOperateLogRequest);

        } finally {
            reentrantLock.unlock();
        }

        return Boolean.TRUE;
    }

    @Override
    public Page<GetAirportListResponseDTO> getAirportList(GetAirportListRequestDTO getAirportListRequestDTO) {
        QueryWrapper<FeisuanAirport> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(getAirportListRequestDTO)) {
            if (ObjectUtil.isNotNull(getAirportListRequestDTO.getStatus())) {
                queryWrapper.eq("status", getAirportListRequestDTO.getStatus());
            }
            if (StrUtil.isNotBlank(getAirportListRequestDTO.getAirportName())) {
                queryWrapper.eq("airport_name", getAirportListRequestDTO.getAirportName());
            }
        }
        Page<FeisuanAirport> page = airportMapper.selectPage(new Page<>(getAirportListRequestDTO.getCurrentPage(), getAirportListRequestDTO.getPageSize()), queryWrapper);


        Page<GetAirportListResponseDTO> getAirportListResponseDTOPage = MyBatisPlusPageConverter.convertPage(page, GetAirportListResponseDTO.class);

        List<Long> collect = page.getRecords().stream().map(i -> i.getId()).collect(Collectors.toList());

        List<FeisuanAirportDrone> feisuanAirportDrones = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(collect)){

            QueryWrapper<FeisuanAirportDrone> feisuanAirportDroneQueryWrapper = new QueryWrapper<>();

            feisuanAirportDroneQueryWrapper.in("airport_id", page.getRecords().stream().map(i -> i.getId()).collect(Collectors.toList()));
            List<FeisuanAirportDrone> feisuanAirportDrones1 = airportDroneMapper.selectList(feisuanAirportDroneQueryWrapper);

            feisuanAirportDrones.addAll(feisuanAirportDrones1)  ;

        }


        getAirportListResponseDTOPage.setRecords(page.getRecords().stream().map(i -> {
            String message = "风速:< " + i.getWindSpeedThreshold() + " m/s 降雨：< " + i.getRainfallThreshold() + " mm";
            GetAirportListResponseDTO getAirportListResponseDTO = BeanUtil.copyProperties(i, GetAirportListResponseDTO.class);
            getAirportListResponseDTO.setEnvironmentThreshold(message);
            if (i.getStatus() == 1) {

                getAirportListResponseDTO.setStatus("在线");
            }else if (i.getStatus() == 2) {
                getAirportListResponseDTO.setStatus("离线");
            }

            System.out.println("无人机数量=" + feisuanAirportDrones.stream().filter(i1 -> Objects.equals(i1.getAirportId(), i.getId())).collect(Collectors.toList()));

            getAirportListResponseDTO.setDroneNums(Integer.valueOf(feisuanAirportDrones.stream().filter(i1 -> Objects.equals(i1.getAirportId(), i.getId())).collect(Collectors.toList()).size()).longValue());

            return getAirportListResponseDTO;
        }).collect(Collectors.toList()));
        return getAirportListResponseDTOPage;
    }



    @Override
    public Boolean editAirport(EditAirportRequestDTO editAirportRequestDTO) throws IOException {
        try {
            reentrantLock.lock();
            Long startTime = System.nanoTime();

            UpdateWrapper<FeisuanAirport> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", editAirportRequestDTO.getId());
            if (ObjectUtil.isNotNull(editAirportRequestDTO)) {
                    QueryWrapper<FeisuanAirport> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("id", editAirportRequestDTO.getId());
                    FeisuanAirport feisuanAirport = airportMapper.selectOne(queryWrapper);

                    updateWrapper.set(StrUtil.isNotBlank(editAirportRequestDTO.getImageUrl()), "image_url", editAirportRequestDTO.getImageUrl());
//                }

                if (CollectionUtil.isNotEmpty(editAirportRequestDTO.getDroneIds())) {

                    UpdateWrapper<FeisuanAirportDrone> updateWrapper1 = new UpdateWrapper<>();
                    updateWrapper1.eq("airport_id", editAirportRequestDTO.getId());
                    airportDroneMapper.delete(updateWrapper1);
                    List<FeisuanAirportDrone> collect = editAirportRequestDTO.getDroneIds().stream().map(i -> {
                        FeisuanAirportDrone feisuanAirportDrone = new FeisuanAirportDrone();
                        feisuanAirportDrone.setAirportId(editAirportRequestDTO.getId());
                        feisuanAirportDrone.setDroneId(i);
                        return feisuanAirportDrone;
                    }).collect(Collectors.toList());
                    Db.saveBatch(collect);
                }

                if (StrUtil.isNotBlank(editAirportRequestDTO.getAirportName())) {
                    updateWrapper.set("airport_name", editAirportRequestDTO.getAirportName());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getGatewaySn())) {
                    updateWrapper.set("gateway_sn", editAirportRequestDTO.getGatewaySn());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getOrganizationId())) {
                    updateWrapper.set("organization_id", editAirportRequestDTO.getOrganizationId());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getLongitude())) {
                    updateWrapper.set("longitude", editAirportRequestDTO.getLongitude());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getLatitude())) {
                    updateWrapper.set("latitude", editAirportRequestDTO.getLatitude());
                }
                if (StrUtil.isNotBlank(editAirportRequestDTO.getDescription())) {
                    updateWrapper.set("description", editAirportRequestDTO.getDescription());
                }
                if (StrUtil.isNotBlank(editAirportRequestDTO.getIpAddress())) {
                    updateWrapper.set("ip_address", editAirportRequestDTO.getIpAddress());
                }
                if (StrUtil.isNotBlank(editAirportRequestDTO.getVideoAddress())) {
                    updateWrapper.set("video_address", editAirportRequestDTO.getVideoAddress());
                }
                if (StrUtil.isNotBlank(editAirportRequestDTO.getGateway())) {
                    updateWrapper.set("gateway", editAirportRequestDTO.getGateway());

                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getLatitude())) {
                    updateWrapper.set("latitude", editAirportRequestDTO.getLatitude());
                }

                if (ObjectUtil.isNotNull(editAirportRequestDTO.getStatus())) {
                    updateWrapper.set("status", editAirportRequestDTO.getStatus());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getWindSpeedThreshold())) {
                    updateWrapper.set("wind_speed_threshold", editAirportRequestDTO.getWindSpeedThreshold());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getRainfallThreshold())) {
                    updateWrapper.set("rainfall_threshold", editAirportRequestDTO.getRainfallThreshold());
                }
                //飞行状态
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getFlightStatus())) {
                    updateWrapper.set("flight_status", editAirportRequestDTO.getFlightStatus());
                }

                //固件和保养信息更新
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getFirmwareUpgradeStatus())) {
                    updateWrapper.set("firmware_upgrade_status", editAirportRequestDTO.getFirmwareUpgradeStatus());
                }

                if (ObjectUtil.isNotNull(editAirportRequestDTO.getFirmwareVersion())) {
                    updateWrapper.set("firmware_version", editAirportRequestDTO.getFirmwareVersion());
                }

                if (ObjectUtil.isNotNull(editAirportRequestDTO.getLastMaintainTime())) {
                    updateWrapper.set("last_maintain_time", editAirportRequestDTO.getLastMaintainTime());
                }

                if (ObjectUtil.isNotNull(editAirportRequestDTO.getLastMaintainFlightSorties())) {
                    updateWrapper.set("last_maintain_flight_sorties", editAirportRequestDTO.getLastMaintainFlightSorties());
                }

                if (ObjectUtil.isNotNull(editAirportRequestDTO.getMaintainState())) {
                    updateWrapper.set("maintain_state", editAirportRequestDTO.getMaintainState());
                }
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getLastMaintainType())) {
                    updateWrapper.set("last_maintain_type", editAirportRequestDTO.getLastMaintainType());
                }
//                System.out.println("getDTO:"+editAirportRequestDTO);
                if (ObjectUtil.isNotNull(editAirportRequestDTO.getFlightId())) {
                    if (editAirportRequestDTO.getFlightId().equals("1")){
                        updateWrapper.set("flight_id", null);
                    }else{
                        updateWrapper.set("flight_id", editAirportRequestDTO.getFlightId());
                    }
                }
                updateWrapper.set("modify_time",LocalDateTime.now());
            }
            airportMapper.update(new FeisuanAirport(), updateWrapper);

//            Long endTime = System.nanoTime();
//
//            AddOperateLogRequest addOperateLogRequest = new AddOperateLogRequest();
//            addOperateLogRequest.setOperateModule("设备模块");
//            addOperateLogRequest.setOperateName("编辑机场设备");
//            addOperateLogRequest.setOperateResult(Boolean.TRUE);
////            addOperateLogRequest.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
//            addOperateLogRequest.setOperateType(1);
//            addOperateLogRequest.setIpAddress(ActionUtils.getIpInfo());
//            addOperateLogRequest.setExplorer(ActionUtils.getExplorerInfo());
//            addOperateLogRequest.setTimes(endTime - startTime);
//            operateLogApi.addOperateLogRequest(addOperateLogRequest);
        } finally {
            reentrantLock.unlock();
        }

        return Boolean.TRUE;
    }

    @Override
    public GetAirportByIdResponseDTO getAirportById(GetAirportByIdRequestDTO getAirportByIdRequestDTO) {
        if (ObjectUtil.isNotNull(getAirportByIdRequestDTO) && ObjectUtil.isNotNull(getAirportByIdRequestDTO.getId())) {
            FeisuanAirport feisuanAirport = airportMapper.selectById(getAirportByIdRequestDTO.getId());
//            if (!feisuanAirport.getDeleteStatus()) {
            GetAirportByIdResponseDTO getAirportByIdResponseDTO = BeanUtil.copyProperties(feisuanAirport, GetAirportByIdResponseDTO.class);
//                getAirportByIdResponseDTO.setAirportImageUrl("http://www.smile-emo.com/photo/airport/" + feisuanAirport.getAirportImageUrl());
//            QueryWrapper<FeisuanAirportDrone> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("airport_id", getAirportByIdRequestDTO.getId());
//            List<FeisuanAirportDrone> feisuanAirportDrones = airportDroneMapper.selectList(queryWrapper);
//                if (CollectionUtil.isNotEmpty(feisuanAirportDrones)) {
//                    List<Long> collect = feisuanAirportDrones.stream().map(i -> i.getDroneId()).collect(Collectors.toList());
//                    getAirportByIdResponseDTO.setDroneIds(collect);
//                }

            QueryWrapper<FeisuanAirportDrone> airportDroneQueryWrapper = new QueryWrapper<>();
            airportDroneQueryWrapper.eq("airport_id", getAirportByIdRequestDTO.getId());
            List<FeisuanAirportDrone> feisuanAirportDrones1 = airportDroneMapper.selectList(airportDroneQueryWrapper);
            QueryWrapper<FeisuanDrone> feisuanDroneQueryWrapper = new QueryWrapper<>();
            List<Long> collect = feisuanAirportDrones1.stream().map(i -> i.getDroneId()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)) {

                feisuanDroneQueryWrapper.in("id", collect);
                List<FeisuanDrone> feisuanDrones = droneMapper.selectList(feisuanDroneQueryWrapper);

                List<DroneDTO> collect1 = feisuanDrones.stream().map(i -> {
                    DroneDTO droneDTO = BeanUtil.copyProperties(i, DroneDTO.class);
                    switch (i.getStatus()) {
                        case 1:
                            droneDTO.setStatus("作业中");
                            break;
                        case 2:
                            droneDTO.setStatus("待命");
                            break;
                        case 3:
                            droneDTO.setStatus("离线");
                            break;
                    }
                    droneDTO.setTotalTaskTime(TimeUtils.toChineseTime(i.getTotalTaskTime()));
                    return droneDTO;
                }).collect(Collectors.toList());


                getAirportByIdResponseDTO.setDroneDTOs(collect1);
                getAirportByIdResponseDTO.setTotalTaskTime(TimeUtils.toChineseTime(feisuanAirport.getTotalTaskTime()));

                switch (feisuanAirport.getStatus()) {
                    case 1:
                        getAirportByIdResponseDTO.setStatus("在线");
                    case 2:
                        getAirportByIdResponseDTO.setStatus("离线");
                }

                GetOrganizationByIdRequest getOrganizationByIdRequest = new GetOrganizationByIdRequest();
                getOrganizationByIdRequest.setId(feisuanAirport.getOrganizationId());
                R<GetOrganizationByIdResponse> organizationById = organizationApi.getOrganizationById(getOrganizationByIdRequest);
                if (ObjectUtil.isNotNull(organizationById) || ObjectUtil.isNotNull(organizationById.getData())) {
                    getAirportByIdResponseDTO.setOrganizationName(organizationById.getData().getOrganizationName());
                }


            } else {
                getAirportByIdResponseDTO.setDroneDTOs(Collections.emptyList());
            }
            return getAirportByIdResponseDTO;
//            } else {
//                throw new RuntimeException("机场不存在");
//            }
        }
        throw new RuntimeException("传递的参数为空");
    }

    @Override
    public GetAirportByIdResponseDTO getAirportByGatewaySn(GetAirportByIdRequestDTO getAirportByIdRequestDTO) {
        if (ObjectUtil.isNotNull(getAirportByIdRequestDTO) && ObjectUtil.isNotNull(getAirportByIdRequestDTO.getGatewaySn())) {
            QueryWrapper<FeisuanAirport> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("gateway_sn", getAirportByIdRequestDTO.getGatewaySn()); // 使用LambdaQueryWrapper也可以，例如：LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(User::getName, name);
//            return userMapper.selectOne(queryWrapper);
            FeisuanAirport feisuanAirport = airportMapper.selectOne(queryWrapper);
            GetAirportByIdResponseDTO getAirportByIdResponseDTO = BeanUtil.copyProperties(feisuanAirport, GetAirportByIdResponseDTO.class);
            return getAirportByIdResponseDTO;
        }
        throw new RuntimeException("传递的参数为空");
    }


    @Override
    public GetAirportByIdResponseDTO getAirportByGatewaySn(String gatewaySn) {
        QueryWrapper<FeisuanAirport> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("gateway_sn", gatewaySn); // 使用LambdaQueryWrapper也可以，例如：LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(User::getName, name);
        FeisuanAirport feisuanAirport = airportMapper.selectOne(queryWrapper);
        GetAirportByIdResponseDTO getAirportByIdResponseDTO = BeanUtil.copyProperties(feisuanAirport, GetAirportByIdResponseDTO.class);
        return getAirportByIdResponseDTO;
    }

    @Override
    public Boolean deleteAirport(Long id) {
        if (ObjectUtil.isNull(id)) {
            throw new RuntimeException("id不能为空");
        }

        Long startTime = System.nanoTime();

        airportMapper.deleteById(id);

        Long endTime = System.nanoTime();

        AddOperateLogRequest addOperateLogRequest = new AddOperateLogRequest();
        addOperateLogRequest.setOperateModule("设备模块");
        addOperateLogRequest.setOperateName("删除无人机设备");
        addOperateLogRequest.setOperateResult(Boolean.TRUE);
        addOperateLogRequest.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        addOperateLogRequest.setOperateType(1);
        addOperateLogRequest.setIpAddress(ActionUtils.getIpInfo());
        addOperateLogRequest.setExplorer(ActionUtils.getExplorerInfo());
        addOperateLogRequest.setTimes(endTime - startTime);
        operateLogApi.addOperateLogRequest(addOperateLogRequest);

        return Boolean.TRUE;
    }
}
